"use strict";
//  装饰器就是一个方法，可以注入到类，方法，属性参数上来拓展类，属性，方法，参数的功能
//  常见的装饰器有：类装饰器，属性装饰器，方法装饰器，参数装饰器
//  装饰器的写法：普通装饰器（无法传参）装饰器工厂（可传参）
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
//  类装饰器 普通装饰器
function logClass(param) {
    //param代表被修饰的类
    console.log(param);
    param.prototype.run = function () {
        console.log(this.name + '------');
    };
}
var HttpClient = /** @class */ (function () {
    function HttpClient(name) {
        this.name = name;
    }
    HttpClient.prototype.get = function () {
    };
    HttpClient = __decorate([
        logClass
    ], HttpClient);
    return HttpClient;
}());
//  可以使用类为类型 会报错
//  使用any可以不报错
var h = new HttpClient('ywj');
h.run();
console.log(HttpClient.prototype);
//  类装饰器 装饰器工厂
function logClass1(param) {
    return function (target) {
        console.log(target);
        console.log(param);
        target.prototype.url = param;
    };
}
var HttpClient1 = /** @class */ (function () {
    function HttpClient1() {
    }
    HttpClient1.prototype.get = function () {
    };
    HttpClient1 = __decorate([
        logClass1('hello')
    ], HttpClient1);
    return HttpClient1;
}());
var h2 = new HttpClient1();
console.log(h2.url);
//类装饰器 重载类
var HttpClient2 = /** @class */ (function () {
    function HttpClient2() {
        this.name = 'ywj';
    }
    HttpClient2.prototype.get = function () {
        console.log('get方法');
    };
    HttpClient2 = __decorate([
        logClass2
    ], HttpClient2);
    return HttpClient2;
}());
function logClass2(param) {
    return /** @class */ (function (_super) {
        __extends(class_1, _super);
        function class_1() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.name = '修改后的数据';
            return _this;
        }
        class_1.prototype.get = function () {
            console.log('修改后的get方法');
        };
        return class_1;
    }(param));
}
var h3 = new HttpClient2();
h3.get();
//  属性装饰器
//  可以给属性添加默认值
var HttpClient3 = /** @class */ (function () {
    function HttpClient3(name) {
        this.name = name;
    }
    HttpClient3.prototype.get = function () {
        console.log(this.name);
    };
    __decorate([
        logProp('ywj')
    ], HttpClient3.prototype, "name", void 0);
    return HttpClient3;
}());
function logProp(param) {
    return function (target, attr) {
        console.log(param);
        console.log(target);
        console.log(attr);
        target[attr] = param;
    };
}
var h4 = new HttpClient3('ywjssss');
h4.get();
console.log(h4.name);
console.log(HttpClient3.prototype);
//  方法装饰器
var HttpClient4 = /** @class */ (function () {
    function HttpClient4() {
    }
    HttpClient4.prototype.get = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        console.log('之前的方法');
    };
    __decorate([
        get('hello')
    ], HttpClient4.prototype, "get", null);
    return HttpClient4;
}());
function get(param) {
    //  target原型
    //  methodName 方法名
    //  desc方法描述
    //  target可以拓展类 与类装饰器类似
    return function (target, methodName, desc) {
        console.log(param);
        console.log(target);
        console.log(methodName);
        console.log(desc);
        //  修改之前的方法
        var oldMethod = desc.value;
        desc.value = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            args = args.map(function (value) {
                return String(value);
            });
            console.log(args);
            oldMethod.apply(this, args);
        };
    };
}
var h5 = new HttpClient4();
h5.get('123', 123, false);
//  方法参数装饰器
var HttpClient5 = /** @class */ (function () {
    function HttpClient5() {
    }
    HttpClient5.prototype.getData = function (uuid) {
    };
    __decorate([
        __param(0, logParam('123'))
    ], HttpClient5.prototype, "getData", null);
    return HttpClient5;
}());
function logParam(param) {
    // target原型链
    // method方法名
    // paramIndex参数索引
    // 用来添加类的一些属性和类装饰器类似
    // 使用较少
    return function (target, methodName, paramIndex) {
        console.log(param);
        console.log(target);
        console.log(methodName);
        console.log(paramIndex);
    };
}
//  执行顺序 属性》方法》方法参数》类
//  多个同类装饰器 先执行后面的装饰器
